package com.zyw.boot.tool;

import com.google.gson.JsonObject;
import com.zyw.boot.tool.util.HttpUtil;

import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public class FileTranslator {

    // 科大讯飞翻译API相关参数
    private static final String APP_ID = "appid";
    private static final String API_KEY = "api_key";// 替换为你的API_KEY
    private static final String API_SECRET = "api_secret"; // 替换为你的API_SECRET
    private static final String API_URL = "https://ntrans.xfyun.cn/v2/ots";

    // 解析翻译结果
    private static String parseTranslationResult(String resultStr) {
        com.google.gson.JsonParser parser = new com.google.gson.JsonParser();
        com.google.gson.JsonObject resultJson = parser.parse(resultStr).getAsJsonObject();
        if (resultJson.has("data") && resultJson.get("data").isJsonObject()) {
            String dst = resultJson.getAsJsonObject("data").getAsJsonObject("result").getAsJsonObject("trans_result").get("dst").getAsString();

            return dst;
        }
        return "翻译失败";
    }

    // 输入和输出文件夹路径
    private static final String INPUT_FOLDER = "input_dir"; // 输入文件夹路径
    private static final String OUTPUT_FOLDER = "out_dir"; // 输出文件夹路径

    private static final String LOG_FOLDER = "D://log"; // 日志文件夹路径

    public static void main(String[] args) {
        // 创建输出文件夹（如果不存在）
        createFolder(OUTPUT_FOLDER);
        createFolder(LOG_FOLDER);

        // 获取输入文件夹中的所有文件
        File folder = new File(INPUT_FOLDER);
        File[] files = folder.listFiles(File::isFile);

        if (files == null || files.length == 0) {
            System.out.println("输入文件夹中没有文件！");
            return;
        }

        // 遍历每个文件
        for (File file : files) {
            try {
                // 读取文件内容
                String content = readFile(file);

                // 翻译内容
                String translatedContent = translateLargeText(content);

                // 保存翻译后的内容到输出文件夹
                saveToFile(translatedContent, OUTPUT_FOLDER, file.getName());

                System.out.println("文件 " + file.getName() + " 翻译完成！");
            } catch (Exception e) {
                // 记录错误日志
                logError("处理文件 " + file.getName() + " 时出错: " + e.getMessage());
                e.printStackTrace();
            }
        }

        System.out.println("所有文件翻译完成！");
    }

    // 创建文件夹
    private static void createFolder(String folderPath) {
        File folder = new File(folderPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
    }

    // 读取文件内容
    private static String readFile(File file) throws IOException {
        return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
    }

    // 调用科大讯飞翻译API，处理大文本
    private static String translateLargeText(String text) throws Exception {
        int maxChunkSize = 5000; // 科大讯飞API单次翻译最大字符数限制
        List<String> chunks = splitTextIntoChunks(text, maxChunkSize);
        StringBuilder translatedContent = new StringBuilder();

        for (String chunk : chunks) {
            String translatedChunk = translate(chunk);
            translatedContent.append(translatedChunk);
        }

        return translatedContent.toString();
    }

    // 将文本分割成多个小块，每个块不超过maxChunkSize字符
    private static List<String> splitTextIntoChunks(String text, int maxChunkSize) {
        List<String> chunks = new ArrayList<>();
        int textLength = text.length();
        int startIndex = 0;

        while (startIndex < textLength) {
            int endIndex = Math.min(startIndex + maxChunkSize, textLength);
            String chunk = text.substring(startIndex, endIndex);
            chunks.add(chunk);
            startIndex = endIndex;
        }

        return chunks;
    }

    // 调用科大讯飞翻译API
    private static String translate(String text) throws Exception {
        // 获取当前时间戳
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        Date dateD = new Date();
        String date = format.format(dateD);

        // 对body进行sha256签名,生成digest头部，POST请求必须对body验证
        String body = buildHttpBody(text);
        String digestBase64 = "SHA-256=" + signBody(body);

        // hmacsha256加密原始字符串
        StringBuilder builder = new StringBuilder("host: ").append(new URL(API_URL).getHost()).append("\n")
                .append("date: ").append(date).append("\n")
                .append("POST ").append(new URL(API_URL).getPath()).append(" HTTP/1.1").append("\n")
                .append("digest: ").append(digestBase64);
        String sha = hmacsign(builder.toString(), API_SECRET);

        // 组装authorization
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", API_KEY, "hmac-sha256", "host date request-line digest", sha);

        // 构建请求头
        Map<String, String> header = new HashMap<>();
        header.put("Authorization", authorization);
        header.put("Content-Type", "application/json");
        header.put("Accept", "application/json,version=1.0");
        header.put("Host", new URL(API_URL).getHost());
        header.put("Date", date);
        header.put("Digest", digestBase64);

        // 发送请求并获取响应
        Map<String, Object> resultMap = HttpUtil.doPost2(API_URL, header, body);
        if (resultMap != null && resultMap.containsKey("body")) {
            String resultStr = resultMap.get("body").toString();
            // 解析翻译结果
            return parseTranslationResult(resultStr);
        } else {
            throw new Exception("翻译请求失败！");
        }
    }

    // 组装http请求体
    private static String buildHttpBody(String text) throws Exception {
        JsonObject body = new JsonObject();
        JsonObject common = new JsonObject();
        JsonObject business = new JsonObject();
        JsonObject data = new JsonObject();

        // 填充common
        common.addProperty("app_id", APP_ID);

        // 填充business
        business.addProperty("from", "en"); // 源语言（假设为英文）
        business.addProperty("to", "zh"); // 目标语言

        // 填充data
        byte[] textByte = text.getBytes("UTF-8");
        String textBase64 = new String(Base64.getEncoder().encodeToString(textByte));
        data.addProperty("text", textBase64);

        // 填充body
        body.add("common", common);
        body.add("business", business);
        body.add("data", data);

        return body.toString();
    }

    // 对body进行SHA-256加密
    private static String signBody(String body) throws Exception {
        MessageDigest messageDigest;
        String encodestr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(body.getBytes("UTF-8"));
            encodestr = new String(Base64.getEncoder().encodeToString(messageDigest.digest()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encodestr;
    }

    // hmacsha256加密
    private static String hmacsign(String signature, String apiSecret) throws Exception {
        Charset charset = Charset.forName("UTF-8");
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("hmacsha256");
        javax.crypto.spec.SecretKeySpec spec = new javax.crypto.spec.SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
        mac.init(spec);
        byte[] hexDigits = mac.doFinal(signature.getBytes(charset));
        return new String(Base64.getEncoder().encodeToString(hexDigits));
    }



    // 保存翻译后的内容到文件
    private static void saveToFile(String content, String folder, String fileName) throws IOException {
        File outputFile = new File(folder, fileName);
        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(outputFile), StandardCharsets.UTF_8))) {
            writer.write(content);
        }
    }

    // 记录错误日志
    private static void logError(String message) {
        try {
            File logFile = new File(LOG_FOLDER, "translation_errors.log");
            try (PrintWriter writer = new PrintWriter(new FileOutputStream(logFile, true))) {
                writer.println(new Date() + " - " + message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}